<!--
 * @LastEditTime: 2023-11-07 09:59:45
 * @FilePath: \bdcar-net\src\views\comlbs\orderConfiguration\index.vue
 * @Description: 指令下发
-->
<template>
  <div class="app-container">
    <!-- 指令树 -->
    <treeRightMenu class="leftTree" id="leftTreeDom" ref="leftTreeDom" :leftTreeNodeClick='leftTreeNodeClick'
      :setSelOption="setSelOption" :orderConfigEditHandle="orderConfigEditHandle" :setConfigState="setConfigState">
    </treeRightMenu>
    <div class="centerDom" id="centerDom">
      <!-- 指令设置与编辑 -->
      <div class="topDom" id="topDom">
        <div class="top-title">
          <div class="title">
            <span>{{ title ? title : '指令' }}</span>
          </div>
          <el-button plain type="info" @click="cancelOrderItem" v-if="configState == 'orderConfigSubmit'"
            class="cancelBtn">取消</el-button>
          <el-button type="primary" plain icon="Position" v-if="configState == 'orderConfigSubmit'"
            @click="submitOrderItem()" v-hasPermi="['comlbs:orderConfiguration:send']">发送指令</el-button>
        </div>
        <div class="topDom_body">
          <div class="top">
            <template v-if="configState == 'orderConfigEdit'">
              <el-button class="addBtn" type="primary" plain @click="addOrderItem">新增</el-button>
              <el-tooltip effect="dark" content="输入框：允许输入任何字符的框体<br/>
            时间选择器：选择时间的输入框，格式为2023-11-06 12:00:00<br/>
            字典下拉框：下拉框，下拉内容从字典读取，故字段需要与字典字段一致<br/>
            布尔下拉框：下拉框，是传递true，否传递false<br/>
            接口下拉框：下拉框，下拉内容从接口获取，返回的字段属性需要与字典的一致，如果返回多余的字段属性，当选择后会自动匹配<br/>
            接口多选下拉框：在接口下拉框的基础上增加了多选<br/>
            无输入框：不需要输入的框体<br/>
            数字输入框：只能输入数字的框体<br/>" placement="top-start" :raw-content="true">
                <el-icon>
                  <QuestionFilled />
                </el-icon>
              </el-tooltip>
              <el-button class="cancelBtn" plain type="info" @click="cancelOrderItem">取消</el-button>
              <el-button class="saveBtn" type="success" plain @click="saveOrderItem">保存</el-button>
            </template>
            <template v-else-if="configState == 'orderConfigSubmit'">
              <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange"
                style="margin-right:16px">
                <span style="font-size: 16px;">全选</span>
              </el-checkbox>
              <el-tooltip effect="dark" content="存在勾选框的项为可选参数，其他为必填参数" placement="top-start" :raw-content="true">
                <el-icon>
                  <QuestionFilled />
                </el-icon>
              </el-tooltip>
            </template>
          </div>
          <div class="content">
            <template v-if="configState == 'orderConfigEdit'">
              <div class="item" v-for="(v, i) in confValue" :key="i">
                <el-input v-model="v.name" placeholder="请输入中文名称" class="myInput"></el-input>
                <el-input v-model="v.prop" placeholder="请输入英文字段" class="myInput"></el-input>
                <el-input v-model="v.value" placeholder="请输入默认值" class="myInput"></el-input>
                <el-input v-model="v.tips" placeholder="请输入提示信息" class="myInput"></el-input>
                <el-select v-model="v.require" placeholder="是否必填" class="myInput" style="width: 100px;">
                  <el-option label="必填" :value="true"> </el-option>
                  <el-option label="非必填" :value="false"> </el-option>
                </el-select>
                <el-select v-model="v.type" placeholder="请选择类型" class="myInput">
                  <el-option v-for="item in sel_option.orderEditItemType" :key="item.value" :label="item.label"
                    :value="item.value">
                  </el-option>
                </el-select>
                <el-input v-model="v.url" v-if="v.type == 'interfaceSelect' || v.type == 'interfaceMupti'"
                  placeholder="请输入接口" class="myInput"></el-input>
                <div @click="deleteOrderItem(i)" class="delete-btn">
                  <el-icon>
                    <Delete />
                  </el-icon>
                </div>
              </div>
            </template>
            <template v-else-if="configState == 'orderConfigSubmit'">
              <!-- 必填列表 -->
              <ul class="require-list">
                <li v-for="(v, i) in requireConf" :key="i" class="selectItem">
                  {{ v.name }}
                  <polymorphicInput :data="v" :sel_option="sel_option" :setOtherValue='setOtherValue'>
                  </polymorphicInput>
                </li>
              </ul>
              <!-- 可选列表 -->
              <el-checkbox-group v-model="checkedConfig" @change="handleCheckedConfigChange">
                <div class="selectItem" v-for="(v, i) in conf" :key="i">
                  <el-checkbox :label="v.prop" :key="v.prop">{{ v.name }}</el-checkbox>
                  <polymorphicInput :data="v" :sel_option="sel_option" :setOtherValue='setOtherValue'>
                  </polymorphicInput>
                </div>
              </el-checkbox-group>
            </template>
            <template v-else>
              <div class="noConfig">
                <img src="@/assets/img/index/nodata.png" />
              </div>
            </template>
          </div>
        </div>
        <div class="moveBtn" v-movetop>
          <div class="logo"></div>
        </div>
      </div>
      <!-- 指令下发记录 -->
      <div class="tableDom" id="tableDom">
        <order-table ref="myTable" :sel_option='sel_option'></order-table>
      </div>
    </div>
    <!-- 车辆树 -->
    <div class="rightTree" id="rightDom" v-loading="refresh">
      <div class="title">
        <div class="rectangle"></div><span>监管对象列表</span>
      </div>
      <instructSelectTree v-if="!refresh" ref="icmTree" :treeList="treeList" :refreshRightTree="refreshRightTree"
        class="instructSelectTree">
      </instructSelectTree>
      <div class="moveBtn" v-move>
        <div class="logo"></div>
      </div>
    </div>
  </div>
</template>
<script setup name="OrderConfiguration">
import { getAlltreelist, saveOrder, orderSend } from "@/api/comlbs/orderConfiguration";
import treeRightMenu from './treeRightMenu';
import instructSelectTree from './instructSelectTree';
import orderTable from './orderTable';
import polymorphicInput from './polymorphicInput';
import $store from "@/store/index";
import dayjs from "dayjs"
import { hidePopper } from "@/utils/clearSelect"
import request from "@/utils/request"
import { onMounted } from "vue";
const { proxy } = getCurrentInstance();
//指令配置
const confValue = ref([]);
const title = ref("");
//判断对指令是什么操作
const configState = ref("");

// 勾选相关
const isIndeterminate = ref(false);
const checkAll = ref(false);
const checkedConfig = ref(false);  //存储勾选的配置的prop
const configOptions = ref([]);  //存储所有的配置的prop
const requireConf = ref([]);  //下发指令-必填
const conf = ref([]);//下发指令-非必填

const myTable = ref()
const leftTreeDom = ref()

const refresh = ref(false)
const sel_option = ref({});
sel_option.value = proxy.useDict.apply(this, ["orderSendStatus", "orderEditItemType"]);
function setSelOption(key, data) {
  sel_option.value[key] = data
}
// 右侧树
const treeList = ref([]);
const icmTree = ref(null);

getEquipTreeList();

// 获取指令下发目标树
function getEquipTreeList() {
  getAlltreelist().then(result => {
    refresh.value = false
    if (result.code == 200) {
      let treedata = result.data;
      getDataTree(treedata)
      treeList.value = treedata
    }
  })
}
function getDataTree(data) {
  for (let i = 0; i < data.length; i++) {
    if (data[i].children == null || data[i].children.length < 1) {
      if (data[i].state) {
        if (data[i].state.disabled == 1) {
          data[i].disabled = true  //给叶子节点加属性
        } else if (data[i].state.disabled == 0) {
          data[i].disabled = false//给叶子节点加属性
        }
      }
    } else {
      getDataTree(data[i].children)
    }
  }
}
function setConfigState(val) {
  configState.value = val
}
function refreshRightTree() {
  refresh.value = true
  getEquipTreeList();
}
// 添加指令配置项
function addOrderItem() {
  confValue.value.push({
    name: "",
    prop: "",
    value: "",
    tips: "",
    require: false,
    type: "input",
    url: ""
  })
}
// 保存指令配置项
function saveOrderItem() {
  leftTreeDom.value.InfoSelectData.confValue = confValue.value;
  leftTreeDom.value.editInfo();
}
// 取消指令配置项
function cancelOrderItem() {
  title.value = null;
  setConfigState('');
}
// 删除指令配置项
function deleteOrderItem(i) {
  confValue.value.splice(i, 1);
}
// 发送指令
function submitOrderItem() {
  let carList = [], _this = this, _orderList = [];
  icmTree.value.getCheckedNodes().filter(v => {
    if (v.type === 2) {
      carList.push(v);
    }
  });
  if (carList.length > 0) {
    const checkHash = {};
    checkedConfig.value.forEach(w => {
      checkHash[w] = true
    })
    let InfoSelectData = leftTreeDom.value.InfoSelectData
    carList.forEach((v, i) => {
      let orderObj = {
        "orderId": InfoSelectData.id,//指令id
        "vehicleId": v.id.replace(/^equip_/, ""),//设备id
        "vehicleNum": v.label,//车牌号
        "deviceNo": v.deviceId,//设备id
        "confValue": InfoSelectData.confValue,//配置的指令
        content: {
          "distributeMsgTopic": InfoSelectData.orderType,//指令orderType
          "response": InfoSelectData.response ? true : false,//指令response
          "userId": $store.state.value.user.info.userId,//用户id
          "userName": $store.state.value.user.info.userName,//账号
          "distributeTime": dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss"),//发出时间
          "devNo": v.deviceId,//设备id
          "requestId": String(new Date().getTime() + i)//自定义这条数据id
        }
      };
      function setContent(y) {
        //如果字段需要时number类型则改为number,但若字段值为空时不必转为number(因为空字符串转为number值为0)
        if (GlobalSetting.numberPropList.indexOf(y.prop) !== -1 && y.value != '') {
          y.value = Number(y.value)
        }
        //是否需要传递items
        if (GlobalSetting.newOrders.indexOf(InfoSelectData.orderType) === -1) {
          // 通用
          orderObj.content[y.prop] = y.value;
        } else {
          if (InfoSelectData.orderType === 'QuerySpecifiedParameters_Send') {
            if (orderObj.content.ids) orderObj.content.ids.push(parseInt(y.prop));
            else orderObj.content.ids = [parseInt(y.prop)];
          } else {
            if (orderObj.content.items) orderObj.content.items.push({ id: y.prop, value: y.value });
            else orderObj.content.items = [{ id: y.prop, value: y.value }];
          }
        }
      }
      // 选填项循环
      conf.value.forEach(y => {
        if (!checkHash[y.prop]) return
        setContent(y);
      })
      // 必填项循环
      requireConf.value.forEach(y => {
        setContent(y)
      })
      _orderList.push(orderObj)
    })
    orderSend(_orderList).then(res => {
      if (res.code == 200) {
        myTable.value.getTableData();
        setConfigState("");
        sendOrder(res.data);
        icmTree.value.clearCheckedNode();
      }
    })
  } else {
    proxy.$modal.msgError("请选择设备！");
  }
}
function sendOrder(data) {
  return saveOrder(data).then(res => {
    if (res.code === 200) proxy.$modal.msgSuccess("发送指令成功！");
  })
}
function handleCheckAllChange(val) {
  checkedConfig.value = val ? configOptions.value : [];
  isIndeterminate.value = false
}
function handleCheckedConfigChange(value) {
  let checkedCount = value.length;
  checkAll.value = checkedCount === configOptions.value.length;
  isIndeterminate.value = checkedCount > 0 && checkedCount < configOptions.value.length;
}
function orderConfigEditHandle(titleStr, confList, type) {
  title.value = titleStr;
  setConfigState(type);
  confValue.value = confList;
}
// 左侧树叶子节点点击事件-下发指令
function leftTreeNodeClick(data) {
  //叶子节点的时候才执行
  if (data.hasChild == '0') {
    setConfigState('orderConfigSubmit');
    title.value = data.orderName;
    confValue.value = JSON.parse(JSON.stringify(leftTreeDom.value.InfoSelectData.confValue));
    configOptions.value = [];
    requireConf.value = [];
    conf.value = [];
    confValue.value.forEach(v => {
      // 处理必填
      if (v.require) {
        requireConf.value.push(v)
      } else {
        configOptions.value.push(v.prop);
        conf.value.push(v);
      }
      // 处理框体类型
      if (v.type == 'dictSelect') {
        proxy.setDataByDictType(sel_option.value, v.prop, v.prop);
      } else if (v.type == 'interfaceSelect' || v.type == 'interfaceMupti') {
        request({
          url: v.url,
          method: "get",
        }).then(resp => {
          sel_option.value[v.prop] = resp.data;
        })
      } else if (v.type == 'numberInput') {
        v.value = v.value ? Number(v.value) : 0
      }
    })
    checkAll.value = false
    isIndeterminate.value = false
    checkedConfig.value = []
  }
}
// 如果是外部接口下拉框选中，则自动沾值
function setOtherValue(value, prop) {
  let _data = sel_option.value[prop].find(v => v.value == value)
  confValue.value.forEach(v => {
    if (_data.hasOwnProperty(v.prop)) {
      v.value = _data[v.prop]
    }
  })
}
const vMovetop = {
  mounted(el, binding) {
    el.onmousedown = function (e) {
      var init = e.clientY;
      //要移动的上侧窗体
      var parent = document.getElementById("topDom");
      var initHeight = parent.offsetHeight;
      document.onselectstart = () => {
        return false
      };
      document.ondragstart = () => {
        return false
      };
      //被动移动的下侧窗体
      var otherDomTwo = document.getElementById("tableDom");
      var OtherTwoinitTop = otherDomTwo.offsetTop;
      document.onmousemove = function (e) {
        var end = e.clientY;
        if (initHeight + end - init > 121 && initHeight + end - init < 489) {
          parent.style.height = initHeight + end - init + "px";

          otherDomTwo.style.top = OtherTwoinitTop + end - init + "px";
        }
      };
      document.onmouseup = function () {
        document.onselectstart = null;
        document.ondragstart = null;
        document.onmousemove = document.onmouseup = null;
      };
    };
  }
}
const vMove = {
  mounted(el, binding) {
    el.onmousedown = function (e) {
      var init = e.clientX;
      //要移动的右侧窗体
      var parent = document.getElementById("rightDom");
      var initWidth = parent.offsetWidth;

      //被动移动的左侧窗体
      var otherDom = document.getElementById("centerDom");
      document.onmousemove = function (e) {
        var end = e.clientX;
        if (initWidth - end + init > 290 && initWidth - end + init < 500) {
          parent.style.width = initWidth - end + init - 10 + "px";
          otherDom.style.right = initWidth - end + init + "px";
        }
      };
      document.onmouseup = function () {
        document.onmousemove = document.onmouseup = null;
      };
    };
  }
}

onMounted(() => {
  document.getElementsByClassName("content")[0].addEventListener("scroll", hidePopper, true);
})
onActivated(() => {
  document.getElementsByClassName("content")[0].addEventListener("scroll", hidePopper, true);
})
onDeactivated(() => {
  document.getElementsByClassName("content")[0].removeEventListener("scroll", hidePopper);
})
</script>
<style scoped lang="scss">
:deep(.my-refresh) {
  color: var(--el-color-primary) !important;
}

.leftTree {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 280px;
  left: 0;
  background-color: #fff;
}

$topHehgt: 256px;

.cancelBtn {
  margin-left: auto;
}

.centerDom {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 290px;
  right: 290px;
  background: #fff;
  overflow: auto;

  .tableDom {
    position: absolute;
    top: $topHehgt;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #fff;
    min-width: 750px;
  }

  .topDom {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: $topHehgt;
    background-color: #fff;
    border-bottom: 10px solid #f2f3f5;
    min-width: 750px;

    .moveBtn {
      width: 100%;
      position: absolute;
      left: 0;
      bottom: 0;
      cursor: s-resize;
      height: 10px;

      .logo {
        background-color: rgb(183, 199, 244);
        width: 60px;
        height: 40%;
        border-radius: 5px;
        position: relative;
        /*脱离文档流*/
        top: 35%;
        /*偏移*/
        margin: 0 auto;
      }
    }

    .top-title {
      display: flex;
      justify-content: flex-start;
      align-items: center;
      padding: 0 16px;
    }

    .title {
      line-height: 40px;
      height: 40px;
      font-weight: 500;
      text-align: left;
      color: #444444;
      font-size: 18px;
      display: flex;
      margin-top: 5px;
      align-items: center;

      img {
        position: relative;
        top: 2px;
        margin: 0 10px;
      }
    }

    .topDom_body {
      height: calc(100% - 55px);
      position: relative;

      .require-list {
        color: #606266;
        font-weight: 400;
        font-size: 14px;
        line-height: 20px;

        li {
          padding-left: 22px;
        }
      }

      .top {
        display: flex;
        align-items: center;
        height: 50px;
        padding: 0 16px;
        box-sizing: border-box;
        color: var(--el-color-primary);

        .addBtn {
          margin-right: 16px;
        }
      }

      .content {
        height: calc(100% - 50px);
        position: absolute;
        right: 0;
        left: 0;
        top: 40px;
        box-sizing: border-box;
        overflow: auto;
        margin: 8px 16px;

        :v-deep(.__view) {
          overflow-x: hidden !important;
        }

        .selectItem {
          width: 50%;
          height: 40px;
          display: inline-flex;
          align-items: center;
          margin: 8px 0;
          position: relative;
          font-weight: 600;
          color: var(--el-color-primary);
          line-height: 0;

          :deep(.el-checkbox__label) {
            font-weight: 600;
          }
        }

        .item {
          height: 40px;
          display: inline-flex;
          align-items: center;
          margin: 5px 0;

          .myInput {
            width: 142px;
            margin-right: 6px;
          }

          .delete-btn {
            display: flex;
            width: 40px;
            height: 32px;
            box-sizing: border-box;
            border-radius: 4px;
            cursor: pointer;
            align-items: center;
            justify-content: center;
            background-color: rgba(234, 73, 66, 0.8);

            &:hover {
              background-color: #ea4942;
            }
          }
        }
      }

      .noConfig {
        display: flex;
        height: 100%;
        overflow: hidden;
        justify-content: center;
        align-items: center;

        img {
          width: 177px;
          height: 128px;
        }
      }
    }
  }
}

.rightTree {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 280px;
  right: 0;
  background-color: #fff;

  .title {
    color: #424242;
    background: #e6efff;
    font-weight: 600;
    font-size: 16px;
    line-height: 30px;
    display: flex;
    align-items: center;
    margin: 16px;
    box-sizing: border-box;
  }

  .instructSelectTree {
    padding: 16px;
    padding-top: 0;
    height: 100%;
    box-sizing: border-box;
    height: calc(100% - 62px);
  }

  .moveBtn {
    width: 10px;
    position: absolute;
    left: 0;
    top: 0;
    cursor: col-resize;
    height: 100%;

    .logo {
      background-color: rgb(183, 199, 244);
      width: 40%;
      height: 60px;
      border-radius: 5px;
      position: relative;
      /*脱离文档流*/
      top: 35%;
      /*偏移*/
      margin: 0 auto;
    }
  }
}
</style>